/*
 * =====================================================================================
 *
 *       Filename:  main_vm2.cpp
 *
 *    Description: Interpolatrion
 *
 *        Version:  1.0
 *        Created:  10/27/2012 09:16:13 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Sergey Gvozdarev
 *   Organization:  MIPT
 *
 * =====================================================================================
 */

#include <iostream>
#include <fstream>
#include <string>

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>

#include <boost/numeric/ublas/operations.hpp>
#include <boost/numeric/ublas/operation.hpp>
#include <boost/numeric/ublas/triangular.hpp>

#include <boost/numeric/ublas/io.hpp>

#include "definitions.hpp"
#include "inter.hpp"

#define M 3


Matrix D;
Matrix Res;

int N;
real_t Step;
real_t Min, Max;

bool ReadFile( std::string file);
bool WriteFile( std::string file);

void FindMinMax( real_t * min, real_t * max);

inline real_t l( int i, real_t x);
inline real_t L( real_t x);



int main ( int argc, char *argv[] )
{
    using std::cout;
    using std::endl;
    using boost::numeric::ublas::prod;
    using boost::numeric::ublas::inner_prod;
    using boost::numeric::ublas::norm_1;

    ReadFile( "data.txt");

    FindMinMax( &Min, &Max);
    Step = ( Max - Min) / N / M;


    cout << "D=\t" << D << endl;
    cout << "N=\t" << N << endl;
    cout << "from\t" << Min << endl;
    cout << "to  \t" << Max << endl;
    cout << "Step:\t" << Step << endl;
////////////////////////////////////


    for ( int k = 1; k < N - 1; k++)
    {
        real_t curr_x = Min;

        for ( int i = 0; i < N * M; i++)
        {
            real_t r;
            if ( k <= N/2-1)
            {
                r = 1.0 * k / ( N/2 - 1);
            }
            else
            {
                r = 1.0 * ( 1.0 -  1.0 / ( N/2 - 1));
            }

            cout << k << " " << r << endl;
            Res( i, 0) = curr_x;
            Res( i, 1) = ( Res( i, 1) + INTER::F( curr_x, D( 0,0), D( 0,1), D( k, 0), D( k,1), D( N -1,0), D( N - 1,1))) / 2*r;

            curr_x += Step;
        }

    }
    cout << "===============" << endl;
    cout << Res << endl;
    WriteFile( "res.txt");
    return 0;
}



bool ReadFile( std::string file)
{
    std::fstream fin;

    fin.open( file.c_str(), std::fstream::in);

    fin >> N;

    D.resize( N , 2, false);
    Res.resize( N * M, 2, false);

    for ( int i = 0; i < N; i++)
    {
        real_t x,y;

        fin >> x;
        fin >> y;

         D( i, 0) = x;
         D( i, 1) = y;
    }
    fin.close();
    return true;
}

bool WriteFile( std::string file)
{
    std::fstream fout;

    fout.open( file.c_str(), std::fstream::out);


    for ( int i = 0; i < N * M; i++)
    {
        fout << Res( i, 0) << ";" << Res( i, 1) << "\n";
    }
    fout.close();
    return true;
}

void FindMinMax( real_t * min, real_t * max)
{
    *max = *min = D( 0, 0);

    for ( int i = 1; i < N; i++)
    {
        if ( D( i, 0) < *min)
        {
            *min = D( i, 0);
        }
        if ( D( i, 0) > *max)
        {
            *max = D( i, 0);
        }
    }
}

inline real_t l( int i, real_t x)
{
    real_t res = 1.0;
    for ( int j = 0; j < N; j++)
    {
        if ( i == j)
        {
            continue;
        }
        real_t tmp =( x - D( j, 0)) / ( D( i, 0) - D( j, 0));

        res *= tmp;

    }

    std::cout << res << std::endl;

    return res;
}

inline real_t L( real_t x)
{
    real_t res = 0.0;
    for ( int i = 0; i < N; i++)
    {
        res += D( i, 1) * l( i, x);
    }
    return res;
}




